<script setup lang="ts">
import { computed, ComputedRef, nextTick, onBeforeUnmount, onMounted, reactive, Ref, ref } from "vue";
import { storeToRefs } from "pinia";
import { ElMessage } from "element-plus";
import type { UploadFile, UploadFiles, UploadProps, UploadRawFile } from "element-plus/es/components/upload";
import useSpuStore from "@/pinia/modules/product/spuStore/spuStore.ts";
import { saleAttributeInfo, spu, spuImage } from "@/api/product/spuApi/interface.ts";
import { Awaitable } from "element-plus/lib/utils";
import { addSpuOrUpdateSpuAPI } from "@/api/product/spuApi/spu.ts";
import useTabNavStore from "@/pinia/modules/product/attributeStore/tabNavStore/tabNavStore.ts";

const spuStore = useSpuStore();
const tabNavStore = useTabNavStore();
const { categoryId } = storeToRefs(tabNavStore);
const { trademarkList, spuImageList, spuSaleAttributeList, selectSaleAttribute, saleAttrIdAndName, currentSpu, edit } = storeToRefs(spuStore);

const inputRef = ref();
const dialogVisible: Ref<boolean> = ref<boolean>(false);
const dialogImageUrl: Ref<string> = ref("");

/* 带给服务器的spu参数对象(添加或修改xpu) */
const spuInfo: spu = reactive<spu>({
  tmId: "", // 品牌ID
  category3Id: "", // 三级分类ID
  spuName: "", // spu名字
  description: "", // spu描述
  spuImageList: [], // spu图片列表
  spuSaleAttrList: [], // spu销售属性列表
});

/* 获取spu所有品牌列表的回调函数 */
const fetchTrademarkList = async () => {
  try {
    await spuStore.fetchTrademarkList();
    ElMessage.success("品牌列表获取成功");
  } catch (error: any) {
    ElMessage.error(error.message);
  }
};
/* 获取spu所有销售属性列表的回调函数 */
const fetchBaseSaleAttributeList = async () => {
  try {
    await spuStore.fetchBaseSaleAttributeList();
    ElMessage.success("销售属性获取成功");
  } catch (error: any) {
    ElMessage.error(error.message);
  }
};
/* spu数据回显的回调函数 */
const findSpu = () => {
  if (!edit.value) return;
  Object.assign(spuInfo, currentSpu.value);
};
/* 点击添加销售属性按钮的回调函数 */
const handleAddSaleAttribute = () => {
  /*{ baseSaleAttrId: number;saleAttrName: number;spuSaleAttrValueList:[]} */
  const [baseSaleAttrId, saleAttrName] = saleAttrIdAndName.value.split(":");
  const saleAttr: saleAttributeInfo = { baseSaleAttrId, saleAttrName, spuSaleAttrValueList: [] };
  spuSaleAttributeList.value.push(saleAttr);
  saleAttrIdAndName.value = "";
};
/* 点击添加销售属性值按钮的回调函数 */
const handleAddSaleAttributeValue = (saleAttribute: saleAttributeInfo) => {
  saleAttribute.flag = true;
  nextTick(() => {
    inputRef.value.focus();
  });
};
/* 点击tag删除销售属性值 */
const handleDeleteSaleAttributeValue = (saleAttribute: saleAttributeInfo, index: number) => {
  saleAttribute.spuSaleAttrValueList.splice(index, 1);
};

/* 属性值输入框失去焦点的回调函数 */
const handleBlur = (saleAttribute: saleAttributeInfo) => {
  const { saleAttrValueName, baseSaleAttrId } = saleAttribute;
  saleAttribute.spuSaleAttrValueList.push({ saleAttrValueName, baseSaleAttrId });
  saleAttribute.flag = false;
  saleAttribute.saleAttrValueName = "";
};
/* 点击删除销售属性按钮的回调函数 */
const handleDeleteSaleAttribute = (index: number) => {
  spuSaleAttributeList.value.splice(index);
};
/* 点击取消按钮的回调函数 */
const handleCancel = () => {
  spuStore.changeScreen(0);
};
/* 点击文件列表中已上传的图片的回调函数 */
const handlePictureCardPreview = (uploadFile: UploadFile): void => {
  dialogVisible.value = true;
  dialogImageUrl.value = uploadFile.url as string;
};
/* 文件上传成功的回调函数 */
const handleUploadSuccess = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
  if (response.code === 200) {
    ElMessage.success("图片上传成功");
  } else {
    ElMessage.error("图片上传失败");
    console.log(uploadFile, uploadFiles);
  }
};
/* 图片上传之前的回调函数 */
const handleBeforeUpload: UploadProps["beforeUpload"] = (rawFile: UploadRawFile): Awaitable<boolean> => {
  const isImage: boolean = rawFile.type.startsWith("image");
  const size: boolean = rawFile.size / 1024 / 1024 > 2;
  if (!isImage) {
    ElMessage.error("只能上传图片");
    return false;
  } else if (size) {
    ElMessage.error("上传的图片不能超过2MB!");
    return false;
  }
  return true;
};
/* 选择spu销售属性下拉框的提示文本 */
const spuSaleAttrPlc: ComputedRef<string> = computed<string>(() => {
  return selectSaleAttribute.value.length !== 0 ? `还有${selectSaleAttribute.value.length}个销售属性未选择` : "暂无销售属性";
});

/* 点击保存按钮的回调函数 */
const handleSubmit = async () => {
  const imageList = spuImageList.value.map((item: spuImage) => {
    return {
      imgName: item.name,
      imgUrl: item.response && item.response.data || item.imgUrl,
    };
  });

  const saleAttrList = spuSaleAttributeList.value;
  spuInfo.spuImageList = imageList;
  spuInfo.spuSaleAttrList = saleAttrList;

  if (!spuInfo.id) spuInfo.category3Id = categoryId.value.category3Id;

  try {
    await addSpuOrUpdateSpuAPI(spuInfo);
    await spuStore.fetchSpuList({ page: 1, limit: 10 }, categoryId.value.category3Id);
    spuStore.changeScreen(0);
    ElMessage.success("成功");
  } catch (error: any) {
    ElMessage.error(error.message);
  }

};

onMounted(() => {
  // 获取spu所有品牌列表
  fetchTrademarkList();
  // 获取spu所有销售属性列表
  fetchBaseSaleAttributeList();
  // spu数据回显
  findSpu();
});

onBeforeUnmount(() => {
  spuStore.spuImageList = [];
});
</script>

<template>
  <div class="spuForm">
    <el-form label-width="100px" :model="spuInfo">
      <el-form-item label="SPU名称">
        <el-input placeholder="请输入SPU的名称" v-model="spuInfo.spuName"></el-input>
      </el-form-item>
      <el-form-item label="SPU品牌">
        <el-select v-model="spuInfo.tmId" placeholder="请选择SPU品牌">
          <el-option v-for="(trademark) in trademarkList" :value="trademark.id" :label="trademark.tmName" :key="trademark.id"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
        <el-input type="textarea" placeholder="请输入SPU的描述" :rows="5" v-model="spuInfo.description"></el-input>
      </el-form-item>
      <el-form-item label="SPU照片墙">
        <el-upload
          v-model:file-list="spuImageList" action="/api/admin/product/fileUpload" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-success="handleUploadSuccess" :before-upload="handleBeforeUpload">
          <el-icon>
            <Plus />
          </el-icon>
        </el-upload>
        <el-dialog width="20%" title="预览模式" v-model="dialogVisible">
          <img :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>
      <el-form-item label="SPU销售属性">
        <el-select v-model="saleAttrIdAndName" :placeholder="spuSaleAttrPlc">
          <el-option v-for="(saleAttribute) in selectSaleAttribute" :value="`${saleAttribute.id}:${saleAttribute.name}`" :label="saleAttribute.name" :key="saleAttribute.id"></el-option>
        </el-select>
        <el-button type="primary" icon="Plus" @click="handleAddSaleAttribute" :disabled="saleAttrIdAndName.length===0">添加销售属性</el-button>
      </el-form-item>
      <el-form-item>
        <el-table border stripe :data="spuSaleAttributeList">
          <el-table-column label="序号" type="index" width="100px" align="center"></el-table-column>
          <el-table-column label="销售属性名" align="center" prop="saleAttrName"></el-table-column>
          <el-table-column label="销售属性值" align="center">
            <template #default="{row,$index}">
              <el-tag type="info" effect="dark" v-for="(spuSaleAttributeValue) in row.spuSaleAttrValueList" :key="spuSaleAttributeValue.id" closable @close="handleDeleteSaleAttributeValue(row,$index)">{{ spuSaleAttributeValue.saleAttrValueName }}
              </el-tag>
              <el-input placeholder="输入销售属性值" size="small" ref="inputRef" v-if="row.flag" @blur="handleBlur(row)" v-model="row.saleAttrValueName"></el-input>
              <el-button type="primary" icon="Plus" size="small" v-else @click="handleAddSaleAttributeValue(row)">添加销售属性值</el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center">
            <template #default="{$index}">
              <el-button type="danger" icon="Delete" @click="handleDeleteSaleAttribute($index)">删除销售属性</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleSubmit">保存</el-button>
        <el-button type="danger" @click="handleCancel">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<style scoped lang="scss">
.spuForm {
  .el-button {
    margin-left: 10px;
  }

  :deep(.el-dialog) {
    width: 30%;

    .el-dialog__body {
      display: flex;
      justify-content: center;
      align-items: center;

      img {
        width: 60%;
      }
    }
  }

  .el-table {
    .el-input {
      width: 20%;
    }

    .el-tag {
      margin: 0 10px;
    }
  }

}
</style>
